package com.jfree.nettyshow.entity;


import com.alibaba.fastjson.JSON;
import com.jfree.nettyshow.common.CommonConstant;
import com.jfree.nettyshow.common.MessageUtil;
import com.jfree.nettyshow.common.Result;
import com.jfree.nettyshow.config.NettyConfiguration;
import com.jfree.nettyshow.inter.TaskHandler;
import io.netty.channel.Channel;
import io.netty.util.AttributeKey;
import org.slf4j.Logger;
import org.slf4j.LoggerFactory;

import java.util.concurrent.Callable;

public class BaseBusinessTask implements Callable<Result> {

    private AttributeKey<Session> attributeKey = AttributeKey.valueOf(CommonConstant.SESSION_CHANNEL_KEY);

    private static Logger logger = LoggerFactory.getLogger(BaseBusinessTask.class);
    private Message message;

    private Channel channel;


    public Result call() throws Exception {
        TaskHandler handler = NettyConfiguration.getHandlerManager().getHandler(message.getVersion(), message.getActionType());
        Result result = null;
        if (handler == null) {
            result = Result.failServer();//TODO 这里可以记录失败次数，达到一定次数断开连接，且定时清理
            logger.error("通信处理业务错误:channelId:" + channel.id().asShortText() + ",没匹配的handler");
        } else {
            try {
                result = handler.action(message);

            } catch (Exception e) {
                logger.error("通信处理业务错误:channelId:" + channel.id().asShortText() + ",cause:" + e.toString());
                result = Result.failServer();
            } finally {
                MessageUtil.clearMessage(message);
                this.message = null;
                this.channel = null; // 线程和对象绑定则不用清除

            }
        }
        try {
            out(result);
        } catch (Exception e) {
            logger.error("---" + channel.id().asShortText() + "发送异常---,result=" + result.toString());
            Session session = null;
            if ((session = channel.attr(attributeKey).get()) != null) {
                //考虑是否关闭连接
                session.setLastWriteErrTime(System.currentTimeMillis());
            }
        }
        return null;//目前不需要返回值。
    }


    private void out(Result result) {
        if (result == null) {
            logger.info("result返回为null不发送消息");
            return;
        }
        if (channel.isWritable()) {
            channel.writeAndFlush(JSON.toJSONString(result));
        }else{
            //todo 当不能写时做好补偿方案
        }

        logger.info("sessionId:" + channel.id().asShortText() + ",返回消息：" + result.toString());
    }

    public Message getMessage() {
        return message;
    }

    public BaseBusinessTask setMessage(Message message) {
        this.message = message;
        return this;
    }

    public Channel getChannel() {
        return channel;
    }

    public BaseBusinessTask setChannel(Channel channel) {
        this.channel = channel;
        return this;
    }
}
